<template>
  <div>

  </div>
</template>

<script setup lang="ts">
import { ref, reactive, isRef, unref, toRef, toRefs, isProxy, readonly, shallowReactive, shallowReadonly, isReactive, isReadonly } from 'vue'
const foo = ref('foo')
console.log(isRef(foo)) // true，isRef 检查某个值是否为 ref
if (isRef(foo)) { // isRef的返回值是一个类型谓词，isRef可以被用作类型守卫
  console.log(foo.value)
}

console.log('==================')

// unref() 如果参数是 ref，则返回内部值，否则返回参数本身。这是 val = isRef(val) ? val.value : val 计算的一个语法糖
const fooVal = unref(foo)
console.log(fooVal) // foo
const barVal = unref(3) // 3
console.log(barVal)

console.log('==================')

// toRef() 可用于为响应式对象上的 property 创建 ref。这样创建的 ref 与其源 property 保持同步，改变源 property 将更新 ref，反之亦然
const state = reactive({
  foo: 1,
  bar: 2
})
const fooRef = toRef(state, 'foo')
console.log(state)
console.log(fooRef)
// 更改该 ref 会更新源属性
fooRef.value++
console.log(state.foo)
// 更改源属性也会更改该 ref
state.foo++
console.log(fooRef.value)

console.log('==================')

// toRefs() 将一个响应式对象转换成一个普通对象，这个普通对象的每个 property 都是指向源对象相应 property 的 ref。每个单独的 ref 都是使用 toRef() 创建的
const info = reactive({
  a: 1,
  b: 1
})

const infoAsRefs = toRefs(info)
console.log(info)
console.log(infoAsRefs)
// 这个 ref 和源属性已经链接上例
infoAsRefs.a.value++
console.log(info.a)

info.a++
console.log(infoAsRefs.a.value)

console.log('==================')

// isProxy() 检查一个对象是否是由 reactive(),readonly(),shallowReactive()或shallowReadonly()创建的代理
console.log(isProxy(info))
const readonlyInfo = readonly(foo)
console.log(isProxy(readonlyInfo))
const shallowRea = shallowReactive({
  a: 's'
})
console.log(isProxy(shallowRea))
const shallowReadon = shallowReadonly(info)
console.log(isProxy(shallowReadon))

console.log('==================')

// isReactive() 检查一个对象是否是由 reactive() 或 shallowReactive() 创建的代理
console.log(isReactive(info))
console.log(isReactive(shallowRea))

// isReadonly() 检查一个对象是否是由 readonly() 或 shallowReadonly() 创建的代理
console.log(isReadonly(readonlyInfo))
console.log(isReadonly(shallowReadon))

</script>

<style scoped>

</style>